﻿#region License
/* ---------------------------------------------------------------- *
 *
 * This file is part of the Xcoordination Application Space
 * ("XcoAppSpace") http://www.xcoordination.com
 *
 * Copyright (C) 2009 Xcoordination http://www.xcoordination.com
 *
 * XcoAppSpace is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General
 * Public License as published by the Free Software Foundation.
 *
 * XcoAppSpace is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/
 * or write to the Free Software Foundation, Inc., 51 Franklin
 * Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * ---------------------------------------------------------------- */
#endregion

using System;
using System.Linq;

namespace XcoAppSpaces.Core
{
	//Info: All Xco attribute classes are sealed because this can improve performance when searching for these attributes.

	/// <summary>
	/// Marks a class as worker extension. When creating a worker, all methods
	/// of a worker extension class that are marked with XcoConcurrent, XcoExclusive
	/// or XcoTeardown are also taken into account as message processing methods.
	/// </summary>
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class XcoWorkerExtensionAttribute : Attribute
	{
		/// <summary>
		/// The list of required types (only either the required types or the optional types should be set).
		/// For all types in this list the worker must have a port in its contract (an exception will be thrown
		/// during instantiation of the worker when a port with one of these types is missing).
		/// </summary>
		public Type[] Required { get; set; }

		/// <summary>
		/// The list of optional types (only either the required types or the optional types should be set).
		/// For these types the worker does not require to have a port, but the port will be used by the worker
		/// extension if it exists.
		/// </summary>
		public Type[] Optional { get; set; }

		/// <summary>
		/// Creates a new XcoWorkerExtensionAttribute.
		/// </summary>
		public XcoWorkerExtensionAttribute()
		{
		}

		/// <summary>
		/// Creates a new XcoWorkerExtensionAttribute.
		/// </summary>
		/// <param name="required">The list of types for which a port must exist at the worker.</param>
		public XcoWorkerExtensionAttribute(params Type[] required)
		{
			this.Required = required;
		}

		/// <summary>
		/// Checks if the given type is required, meaning if a Port{Type} must exist at the worker for this type.
		/// </summary>
		/// <param name="type">The type to be checked.</param>
		/// <returns>True if the type is required.</returns>
		public bool IsTypeRequired(Type type)
		{
			if (Required != null)
				return Required.Contains(type);
			if (Optional != null)
				return !Optional.Contains(type);
			return true; //default is required
		}
	}
}
